home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / labs / fly / fly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  11.8 KB  |  628 lines

  1. /* Copyright (c) Silicon Graphics, Inc. 1996 */
  2.  
  3. /*
  4.  * fly.c 
  5.  * This program allows the user to "fly" through a simple virtual world. 
  6.  *
  7.  * Your challenge - make an even cooler fly!
  8.  *
  9.  * Utility routines are located in flyutil.c
  10.  *
  11.  * MODIFYING THE PROGRAM
  12.  * ---------------------
  13.  * New shapes should be added to the world in the routine drawShapes(). 
  14.  *
  15.  * If new shapes are to be on the path of the autopilot, they must be 
  16.  * near a circle centered at the world origin with a radius of 10.0, 
  17.  * parallel to and raised above the 'floor,' the X-Z plane.
  18.  *
  19.  * As a starting point, here are some good places to center your objects:
  20.  *        ( 0.0, 1.0, 10.0 )
  21.  *        ( 7.0, 1.0, 7.0  )
  22.  *        ( 10.0, 1.0, 0.0 )
  23.  *        ( 7.0, 1.0, -7.0 )
  24.  *        ( 0.0, 1.0, -10.0)
  25.  *        ( -7.0, 1.0, -7.0)
  26.  *        ( -10.0, 1.0, 0.0)
  27.  *        ( -7.0, 1.0, 7.0 )
  28.  *
  29.  *                           INPUT CONTROLS:
  30.  *
  31.  *   <?> key - help, prints this info 
  32.  *   <a> key - <a>utopilot start/stop 
  33.  *   <b> key - <b>lend, alpha blending 
  34.  *   <d> key - toggle <d>ebugging printfs
  35.  *   <g> key - show floor <g>rid
  36.  *   <n> key - <n>ormals drawing toggle 
  37.  *   <r> key - <r>eset eye position 
  38.  *   SPACE key       - cycle wireframe/flat shaded/smooth 
  39.  *   LEFT Mouse      - control moving the eye forward 
  40.  *   MIDDLE Mouse    - control moving the eye backward 
  41.  *   Mouse pointer   - change direction: pull back to go up, forward to dive
  42.  *   Escape key      - exit the program 
  43.  *
  44.  *  Copyright 1991, 1992, 1993, 1994, 1995, 1996, Silicon Graphics,  Inc.
  45.  *  Technical Education Development
  46.  */
  47.  
  48.  
  49. /* fly.h contains function prototypes, and defines constants */
  50. #include <GL/gl.h>
  51. #include <GL/glu.h>
  52. #include <GL/glut.h>
  53.  
  54. #include "fly.h"  
  55.  
  56. /* Global Variables */
  57.  
  58. static enum shapes { FLOOR, TETRA, CUBE, OCTA, DODECA, ICOSA, CONE, FLAG,
  59.              CYLINDER, SPHERE, TORUS, QUAD, FONT };
  60. static enum drawModes { WIREFRAME, SOLID, SIMPLE };
  61.  
  62. enum drawStyles { LIT_SMOOTH, LIT_FLAT, WIRE };
  63.  
  64. extern GLboolean debugFlag;        /* print eye position info? */
  65. extern GLboolean lighting;
  66. extern GLboolean showGridFlag;
  67. extern GLboolean blendFlag;
  68.  
  69. extern GLint drawStyle;
  70. extern GLfloat ex, ey, ez;     /* eye position */
  71. extern GLfloat yaw;         /* eye rotation about y axis in degrees */
  72. extern GLfloat pitch;         /* eye rotation about x axis in degrees */
  73. extern GLfloat velocity;    /* eye velocity */
  74.  
  75. extern GLdouble znear, zfar;    /* z distance to near and far planes */
  76.  
  77. static GLuint outlineFont, filledFont;
  78.  
  79. #define STRING1    "Welcome to OpenGL"
  80. #define STRING2    "Programming 2!"
  81.  
  82. GLvoid
  83. main( int argc, char *argv[] )
  84. {
  85.     GLdouble aspect;
  86.     GLsizei width, height;
  87.  
  88.     glutInit( &argc, argv );
  89.     
  90.     width = glutGet(GLUT_SCREEN_WIDTH); 
  91.     height = glutGet(GLUT_SCREEN_HEIGHT);
  92.     glutInitWindowPosition( width / 4, height / 4 );
  93.     glutInitWindowSize( width / 2, height / 2 );
  94.     glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
  95.     glutCreateWindow( argv[0] );
  96.  
  97.     initgfx();
  98.  
  99.     glutIdleFunc( animate );
  100.     glutVisibilityFunc( visibility );
  101.     glutKeyboardFunc( keyboard );
  102.     glutSpecialFunc( specialkeys );
  103.     glutMouseFunc( mouse );
  104.     glutMotionFunc( motion );
  105.     glutReshapeFunc( reshape );
  106.     glutDisplayFunc( drawScene ); 
  107.  
  108.     printHelp( argv[0] );
  109.  
  110.     glutMainLoop();
  111. }
  112.  
  113. GLvoid
  114. printHelp( char *progname )
  115. {
  116.  
  117.     fprintf(stdout, "\n%s - fly through a simple virtual world.\n",
  118.         progname );
  119.     
  120.     printControls();
  121. }
  122.  
  123. GLvoid
  124. printControls( GLvoid )
  125. {
  126.     fprintf(stdout, "\n\n" 
  127.     "<?> key         - help, prints this info \n" 
  128.     "<a> key        - <a>utopilot start/stop \n"
  129.     "<b> key        - <b>lend, alpha blending \n"
  130.     "<d> key        - <d>ebug mode, prints coords \n"
  131.     "<g> key        - show floor <g>rid \n"
  132.     "<n> key        - <n>ormals drawing toggle \n"
  133.     "<r> key        - <r>eset eye position \n"
  134.     "SPACE key        - cycle wireframe/flat shaded/smooth \n"
  135.     "LEFT Mouse         - control moving the eye forward \n"
  136.     "MIDDLE Mouse         - control moving the eye backward \n"
  137.         "Mouse pointer   - change direction: pull back to go up, forward to dive\n"
  138.     "Escape key        - exit the program \n" );
  139. }
  140.  
  141. /*  Initialize material property, light source, and lighting model, 
  142.  */
  143. GLvoid
  144. initLighting( GLvoid )
  145. {
  146.     GLfloat mat_ambient[] = { 0.25, 0.05, 0.4, 1.0 };
  147.     GLfloat mat_diffuse[] = { 0.5, 0.1, 0.8, 1.0 };
  148.  
  149.     /* mat_specular and mat_shininess are NOT default values */
  150.     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
  151.     GLfloat mat_shininess[] = { 10.0 };
  152.  
  153.     /* light_position is NOT default value */
  154.     GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
  155.  
  156.     /* add code to set the ambient, specular and shininess
  157.      * material properties */
  158.  
  159.  
  160.     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  161.  
  162.     glEnable(GL_LIGHTING);
  163.     glEnable(GL_LIGHT0);
  164. }
  165.  
  166. GLvoid
  167. initgfx( GLvoid )
  168. {
  169.     glClearColor( 0.0, 0.0, 0.0, 1.0 );
  170.     glClearDepth( 1.0 );
  171.  
  172.     glClear( GL_COLOR_BUFFER_BIT );
  173.     glutSwapBuffers();
  174.  
  175.     glEnable( GL_DEPTH_TEST );
  176.  
  177.     initLighting();
  178.  
  179.     resetEye();
  180.  
  181.     outlineFont = createOutlineFont();
  182.     filledFont = createFilledFont();
  183.  
  184.     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  185. }
  186.  
  187. GLvoid 
  188. animate( GLvoid )
  189. {
  190.     moveEye();
  191.  
  192.     /* Tell GLUT to redraw the scene */
  193.     glutPostRedisplay();
  194. }
  195.  
  196. GLvoid
  197. visibility( int state ) 
  198. {
  199.     if (state == GLUT_VISIBLE) {
  200.         glutIdleFunc( animate );
  201.     } else {
  202.         glutIdleFunc( NULL );
  203.     }
  204. }
  205.  
  206. /* Initialize the various input functions */
  207. GLvoid 
  208. keyboard( GLubyte key, GLint x, GLint y ) 
  209. {
  210.     /* all of the following routines are in flyutil.c */
  211.     switch (key) {
  212.     case ' ':
  213.         setDrawStyle();
  214.         break;
  215.     case 'a':
  216.         setAutopilot();
  217.         break;
  218.     case 'b':
  219.         toggleBlend();
  220.         break;
  221.     case 'd':
  222.         setDebug();
  223.         break;
  224.     case 'g':
  225.         toggleShowGrid();
  226.         break;
  227.     case 'n':
  228.         toggleDrawNormals();
  229.         break;
  230.     case 'r':
  231.         resetEye();
  232.         break;
  233.     case '?':
  234.     case '/':
  235.         printControls();
  236.         break;
  237.     case KEY_ESC:
  238.         exit(0);
  239.     }
  240.  
  241.     glutPostRedisplay();
  242. }
  243.  
  244. GLvoid
  245. specialkeys( GLint key, GLint x, GLint y )
  246. {
  247.     switch (key) {
  248.     case GLUT_KEY_UP:
  249.         break;
  250.     case GLUT_KEY_DOWN:
  251.         break;
  252.     }
  253.     glutPostRedisplay();
  254. }
  255.  
  256. GLvoid
  257. mouse( GLint button, GLint state, GLint x, GLint y )
  258. {
  259.     switch (button) {
  260.     case GLUT_LEFT_BUTTON:
  261.     case GLUT_MIDDLE_BUTTON:
  262.         if (state == GLUT_DOWN)
  263.             startMove(button, x, y);
  264.         else
  265.             stopMove();
  266.         glutPostRedisplay();
  267.         break;
  268.  
  269.     case GLUT_RIGHT_BUTTON:
  270.         break;
  271.     }
  272. }
  273.  
  274. GLvoid
  275. motion( GLint x, GLint y )
  276. {
  277.     updatePosition( x, y );
  278.     glutPostRedisplay();
  279. }
  280.  
  281. GLvoid
  282. drawScene( GLvoid )
  283. {
  284.     GLdouble planeABCD[4] = {0.0, -1.0, 0.0, 1.5};
  285.  
  286.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  287.  
  288.     glPushMatrix();
  289.  
  290.         /* accomplish a viewing transformation by moving
  291.          * the world relative to the eye
  292.          */
  293.         glRotatef( pitch, 1.0, 0.0, 0.0 );
  294.         glRotatef( yaw, 0.0, 1.0, 0.0 );
  295.         glTranslatef(-ex,-ey,-ez);
  296.  
  297.         if (lighting) 
  298.             glEnable(GL_LIGHTING);
  299.         else 
  300.             glColor4f( 0.5, 0.5, 0.0, 1.0 );
  301.  
  302.         glPushMatrix();
  303.             computeFloor(); /* function in flyutil.c */    
  304.             drawFloor();
  305.         glPopMatrix();
  306.  
  307.         if (!lighting) 
  308.             glColor4f(0.5, 0.1, 0.8, 0.3);
  309.  
  310.         drawShapes();
  311.  
  312.         if (lighting) 
  313.             glDisable(GL_LIGHTING);
  314.  
  315.         /* draw some 3D text */
  316.         glPushMatrix();
  317.             glTranslatef(-10.1, -2.5, 10.1);
  318.             glScalef(0.1, 0.1, 0.1);
  319.             glColor4f(1.0, 0.7, 0.0, 1.0);
  320.             renderString( filledFont, STRING1 );
  321.         glPopMatrix();
  322.  
  323.         glPushMatrix();
  324.             glRotatef(90, 0, 1, 0);
  325.             glTranslatef(-9.9, -2.5, 10.1);
  326.             glScalef(0.1, 0.1, 0.1);
  327.             glColor4f(0.6, 1, 0.8, 0.6);
  328.             renderString( outlineFont, STRING2 );
  329.         glPopMatrix();
  330.     glPopMatrix();
  331.  
  332.     glutSwapBuffers();
  333.  
  334.     checkError("drawScene");
  335. }
  336.  
  337. GLvoid
  338. drawShapes( GLvoid )
  339. {
  340.     /* add code to change the diffuse property of
  341.       * one or more shapes; make some of the objects
  342.      * transparent. Use glColorMaterial to make the changes fast.
  343.      */
  344.  
  345.     if ( blendFlag )
  346.         disableBlending();
  347.  
  348.     drawMovedShape( TETRA, -5.0, 1.0, 8.7 ); 
  349.     drawMovedShape( CUBE, -8.7, 1.0, 0.5 );
  350.     drawMovedShape( OCTA, 5.0, 1.0, 8.7 );
  351.     drawMovedShape( DODECA, -8.7, 1.0, -5.0 );
  352.     drawMovedShape( ICOSA, -5.0,1.0,-8.7 );
  353.     drawMovedShape( CONE, 8.7,1.0,5.0 );
  354.  
  355.     if ( blendFlag && drawStyle != WIRE )
  356.         enableBlending();
  357.  
  358.     drawMovedShape( CYLINDER, 10.0,1.5,0.0 );
  359.     drawMovedShape( SPHERE, 7.0, 2.0, -7.0 );
  360.     drawMovedShape( TORUS, 0.0, 2.0, -10.0 );
  361.  
  362.     if ( blendFlag && drawStyle != WIRE )
  363.         disableBlending();
  364. }
  365.  
  366. GLvoid
  367. drawMovedShape( GLint currentShape, GLfloat x, GLfloat y, GLfloat z )
  368. {
  369.     glPushMatrix();
  370.     glTranslatef(x, y, z);
  371.     if (drawStyle == WIRE)
  372.     {
  373.         drawShape( currentShape, WIREFRAME );
  374.     }
  375.     else
  376.     {
  377.         drawShape( currentShape, SOLID );
  378.     }
  379.     glPopMatrix();
  380. }
  381.  
  382. GLvoid
  383. drawShape( GLint currentShape, GLint drawMode )
  384. {
  385.     switch( currentShape )
  386.     {
  387.         case TETRA:
  388.             drawTetra( drawMode );
  389.             break;
  390.         case CUBE:
  391.             drawCube( drawMode );
  392.             break;
  393.         case OCTA:
  394.             drawOcta( drawMode );
  395.             break;
  396.         case DODECA:
  397.             drawDodeca( drawMode );
  398.             break;
  399.         case ICOSA:
  400.             drawIcosa( drawMode );
  401.             break;
  402.         case CONE:
  403.             drawCone( drawMode );
  404.             break;
  405.         case CYLINDER:
  406.             drawCylinder( drawMode );
  407.             break;
  408.         case SPHERE:
  409.             drawSphere( drawMode );
  410.             break;
  411.         case TORUS:
  412.             drawTorus( drawMode );
  413.             break;
  414.         default:
  415.             break;
  416.     }
  417. }
  418.         
  419. GLvoid
  420. drawTetra( GLint drawMode )
  421. {            
  422.     switch( drawMode )
  423.     {
  424.         case WIREFRAME:
  425.             glutWireTetrahedron( );
  426.             break;
  427.         case SOLID:
  428.         case SIMPLE:
  429.             glutSolidTetrahedron( );
  430.             break;
  431.         default:
  432.             break;
  433.     }
  434. }                    
  435.  
  436. GLvoid
  437. drawCube( GLint drawMode )
  438. {            
  439.     switch( drawMode )
  440.     {
  441.         case WIREFRAME:
  442.             glutWireCube( 1.0 );
  443.             break;
  444.         case SOLID:
  445.         case SIMPLE:
  446.             glutSolidCube( 1.0 );
  447.             break;
  448.         default:
  449.             break;
  450.     }
  451. }                    
  452.  
  453. GLvoid
  454. drawOcta( GLint drawMode )
  455. {            
  456.     switch( drawMode )
  457.     {
  458.         case WIREFRAME:
  459.             glutWireOctahedron( );
  460.             break;
  461.         case SOLID:
  462.         case SIMPLE:
  463.             glutSolidOctahedron( );
  464.             break;
  465.         default:
  466.             break;
  467.     }
  468. }                    
  469.  
  470.  
  471. GLvoid
  472. drawDodeca( GLint drawMode )
  473. {            
  474.     switch( drawMode )
  475.     {
  476.         case WIREFRAME:
  477.             glutWireDodecahedron( );
  478.             break;
  479.         case SOLID:
  480.         case SIMPLE:
  481.             glutSolidDodecahedron( );
  482.             break;
  483.         default:
  484.             break;
  485.     }
  486. }                    
  487.  
  488. GLvoid
  489. drawIcosa( GLint drawMode )
  490. {            
  491.     switch( drawMode )
  492.     {
  493.         case WIREFRAME:
  494.             glutWireIcosahedron( );
  495.             break;
  496.         case SOLID:
  497.         case SIMPLE:
  498.             glutSolidIcosahedron(  );
  499.             break;
  500.         default:
  501.             break;
  502.     }
  503. }                    
  504.  
  505. GLvoid
  506. drawCone( GLint drawMode )
  507. {            
  508.     glRotatef(-90.0, 1.0, 0.0, 0.0);
  509.     switch( drawMode )
  510.     {
  511.         case WIREFRAME:
  512.             glutWireCone( 1.0, 2.0, 8, 15 );
  513.             break;
  514.         case SOLID:
  515.         case SIMPLE:
  516.             glutSolidCone( 1.0, 2.0, 8, 15 );
  517.             break;
  518.         default:
  519.             break;
  520.     }
  521. }                    
  522.  
  523. GLvoid
  524. drawCylinder( GLint drawMode )
  525. {            
  526.     glRotatef(90.0, 1.0, 0.0, 0.0);
  527.     switch( drawMode )
  528.     {
  529.         case WIREFRAME:
  530.             WireCylinder( 1.0, 2.0 );
  531.             break;
  532.         case SOLID:
  533.         case SIMPLE:
  534.             SolidCylinder( 1.0, 2.0 );
  535.             break;
  536.         default:
  537.             break;
  538.     }
  539. }                    
  540.  
  541. GLvoid
  542. drawSphere( GLint drawMode )
  543. {            
  544.     switch( drawMode )
  545.     {
  546.         case WIREFRAME:
  547.             glutWireSphere( 1.0, 15, 31 );
  548.             break;
  549.         case SOLID:
  550.             glutSolidSphere( 1.0, 15, 31 );
  551.             break;
  552.         case SIMPLE:
  553.             glutSolidIcosahedron( );
  554.             break;
  555.         default:
  556.             break;
  557.     }
  558. }                    
  559.  
  560. GLvoid
  561. drawTorus( GLint drawMode )
  562. {            
  563.     static GLint spinTorus = 0;
  564.     
  565.     glRotatef( (GLfloat)spinTorus, 0.0, 1.0, 0.0 );
  566.     switch( drawMode )
  567.     {
  568.         case WIREFRAME:
  569.             glutWireTorus( 0.25, 0.75, 15, 31 );
  570.             break;
  571.         case SOLID:
  572.             glutSolidTorus( 0.25, 0.75, 15, 31 );
  573.             break;
  574.         case SIMPLE:
  575.             SolidBox ( 2.0, 2.0, 0.5 );
  576.             break;
  577.         default:
  578.             break;
  579.     }
  580.     spinTorus = ( spinTorus + (int)(20*velocity) ) % 360;
  581. }
  582.  
  583. GLvoid
  584. drawFloor( GLvoid )
  585. {
  586.         GLfloat gridDiffuse[] = { 0.5, 0.5, 0.0, 1.0 };
  587.         GLfloat surfaceDiffuse[] = { 0.05, 0.15, 1.0, 1.0 };
  588.  
  589.     static GLboolean first_time = GL_TRUE;
  590.     static GLint floor_mat[2];
  591.  
  592.     if ( first_time ) {
  593.         floor_mat[0] = glGenLists(1);
  594.  
  595.         glNewList(floor_mat[0], GL_COMPILE);
  596.             glMaterialfv(GL_FRONT, GL_AMBIENT, surfaceDiffuse);
  597.             glMaterialfv(GL_FRONT, GL_DIFFUSE, surfaceDiffuse);
  598.         glEndList();
  599.         
  600.         floor_mat[1] = glGenLists(1);
  601.  
  602.         glNewList(floor_mat[1], GL_COMPILE);
  603.             glMaterialfv(GL_FRONT, GL_AMBIENT, gridDiffuse);
  604.             glMaterialfv(GL_FRONT, GL_DIFFUSE, gridDiffuse);
  605.         glEndList();
  606.  
  607.         first_time = GL_FALSE;
  608.     }
  609.  
  610.         if ( drawStyle != WIRE ) {
  611.         glCallList(floor_mat[0]);
  612.         drawFloorFilled();
  613.     }
  614.  
  615.         if ( drawStyle == WIRE || showGridFlag == GL_TRUE ) {
  616.         glCallList(floor_mat[1]);
  617.         drawFloorWire();
  618.     }
  619. }
  620.  
  621. GLvoid resetEye( GLvoid )
  622. {
  623.     register int i;
  624.  
  625.     initEye();
  626. }
  627.  
  628.